package com.monolithiot.sso.controller.front;

import com.monolithiot.sso.common.context.Constants;
import com.monolithiot.sso.common.entity.Authorization;
import com.monolithiot.sso.common.entity.User;
import com.monolithiot.sso.common.exception.AlreadyExistedException;
import com.monolithiot.sso.common.util.CookieUtil;
import com.monolithiot.sso.common.util.EntityUtil;
import com.monolithiot.sso.common.util.SessionAttributeUtil;
import com.monolithiot.sso.common.util.VerifyCodeUtil;
import com.monolithiot.sso.common.vo.BasicJsonResponse;
import com.monolithiot.sso.conf.prop.UploadFileConfigureProperties;
import com.monolithiot.sso.controller.ControllerSupport;
import com.monolithiot.sso.service.AuthorizationService;
import com.monolithiot.sso.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 2018/12/10 Create by 郭文梁
 * UserController
 * 前台用户访问控制器
 *
 * @author 郭文梁
 * @date 2018/12/10
 */
@RestController
@RequestMapping("/front/user")
public class UserController implements ControllerSupport {
    private final UserService userService;
    private final AuthorizationService authorizationService;
    private final UploadFileConfigureProperties uploadFileConfigureProperties;

    @Autowired
    public UserController(UserService userService, AuthorizationService authorizationService, UploadFileConfigureProperties uploadFileConfigureProperties) {
        this.userService = userService;
        this.authorizationService = authorizationService;
        this.uploadFileConfigureProperties = uploadFileConfigureProperties;
    }

    /**
     * 用户注册
     *
     * @param user 用户填入的信息
     * @return BJR with User entity
     */
    @PostMapping("/_register")
    public BasicJsonResponse<User> register(User user,
                                            String verifyCode,
                                            HttpSession session) {
        try {
            EntityUtil.notNull(user, "name", "password");
        } catch (IllegalArgumentException e) {
            return BasicJsonResponse.paramError(e.getMessage());
        }

        if (VerifyCodeUtil.removeIfEquals(session, verifyCode)) {
            try {
                User res = userService.register(user);
                return BasicJsonResponse.ok(res);
            } catch (AlreadyExistedException e) {
                return BasicJsonResponse.paramError(e.getMessage() + "已被注册");
            }
        } else {
            return BasicJsonResponse.paramError("验证码不正确");
        }
    }

    /**
     * 用户登录
     *
     * @param account  账户名（name, mobileNumber, phoneNumber, email）
     * @param password 密码
     * @param session  会话
     * @param remember 是否选择了一星期免登录
     * @return BJR with User entity
     */
    @PostMapping("/_login")
    public BasicJsonResponse<User> login(String account, String password, Boolean remember, HttpSession session,
                                         HttpServletResponse response) {
        //执行登录操作
        User user = userService.login(account, password);
        if (user == null) {
            return BasicJsonResponse.paramError("用户名或密码错误");
        }

        //计算授权时间（记住登录时授权有效时间为1周，否则为两小时）
        int expireIn = remember != null && remember ? Constants.Auth.DEFAULT_REMEMBER_COOKIE_LIVE_TIME : Constants.Auth.DEFAULT_EXPIRE_IN_TIME;

        //新增授权
        Authorization authorization = authorizationService.getAuthorization(user, expireIn);

        //保存用户和授权信息到Session
        SessionAttributeUtil.put(session, Constants.Key.SESSION_USER, user);
        SessionAttributeUtil.put(session, Constants.Key.SESSION_AUTHORIZATION, authorization);

        //是否要做免登录处理
        if (remember != null && remember) {
            response.addCookie(CookieUtil.obtainRememberCookie(Constants.Auth.DEFAULT_REMEMBER_COOKIE_LIVE_TIME,
                    authorization.getToken()));
        }

        //返回信息
        return BasicJsonResponse.ok(user);
    }

    /**
     * 跟美国新用户基本信息
     *
     * @param param   参数
     * @param user    Session中的User
     * @param session 会话
     * @return BJR without data
     */
    @PostMapping("/_update")
    public BasicJsonResponse<Void> update(User param, @SessionAttribute(Constants.Key.SESSION_USER) User user,
                                          HttpSession session) {
        //检查参数
        if (param == null) {
            return BasicJsonResponse.paramError("缺少参数");
        }
        try {
            EntityUtil.notNull(param, "name");
        } catch (IllegalArgumentException e) {
            return BasicJsonResponse.paramError(e.getMessage());
        }

        //拷贝参数
        User copyUser = new User();
        BeanUtils.copyProperties(user, copyUser);
        copyUser.setName(param.getName());
        copyUser.setEmail(param.getEmail());
        copyUser.setMobileNumber(param.getMobileNumber());
        copyUser.setPhoneNumber(param.getPhoneNumber());
        copyUser.setGender(param.getGender());
        copyUser.setProvince(param.getProvince());
        copyUser.setCity(param.getCity());
        copyUser.setDistrict(param.getDistrict());
        copyUser.setAddress(param.getAddress());
        copyUser.setIndustry(param.getIndustry());

        //执行更新操作
        try {
            User res = userService.updateUserInfo(copyUser);
            SessionAttributeUtil.put(session, Constants.Key.SESSION_USER, res);
        } catch (AlreadyExistedException e) {
            return BasicJsonResponse.paramError(e.getMessage() + "已经被注册");
        }
        return BasicJsonResponse.ok();
    }

    /**
     * 获取当前登录的用户
     *
     * @param session 会话
     * @return BJR with user entity
     */
    @GetMapping("/current")
    public BasicJsonResponse<User> currentUser(HttpSession session) {
        User user = SessionAttributeUtil.fromSession(session, User.class, Constants.Key.SESSION_USER);
        if (user == null) {
            return BasicJsonResponse.paramError("未登录");
        } else {
            String prefix = uploadFileConfigureProperties.getPathPrefix() + '/' +
                    uploadFileConfigureProperties.getUserHeadPortrait();
            return BasicJsonResponse.ok(user.cloneAsPrettyPath(prefix));
        }
    }

    /**
     * 用户设置头像
     *
     * @param hpFile  上传的头像文件
     * @param session 会话
     * @return BJR without data
     */
    @PostMapping("/_set-hp")
    public BasicJsonResponse<Void> setHeadPortrait(MultipartFile hpFile, HttpSession session) throws IOException {
        User user = SessionAttributeUtil.fromSession(session, User.class, Constants.Key.SESSION_USER);
        assert user != null;
        User res = userService.setHeadPortrait(user, hpFile);
        assert res != null;
        SessionAttributeUtil.put(session, Constants.Key.SESSION_USER, res);
        return BasicJsonResponse.ok();
    }

    /**
     * 登出操作
     *
     * @param session 会话
     * @return BJR without data
     */
    @PostMapping("/_logout")
    public BasicJsonResponse<Void> logout(HttpSession session) {
        User user = SessionAttributeUtil.fromSession(session, User.class, Constants.Key.SESSION_USER);
        assert user != null;

        Authorization res = authorizationService.deleteByUser(user);
        if (res == null) {
            return BasicJsonResponse.paramError("授权不存在");
        }

        //销毁Session
        session.invalidate();
        return BasicJsonResponse.ok();
    }
}
